<template>
  <div>
    <div class="params head-form">
      <el-form :model="params" label-width="auto">
        <div class="params-form">
          <el-form-item label="核销状态">
            <el-select placeholder="请选择" v-model="params.cancelState" style="flex: 1" @change="init">
              <el-option v-for="(item, index) in verificationType" :value="Number(index)" :label="item"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="关联订单">
            <el-input style="flex: 1" @blur="init" @keyup.enter="init" v-model="params.orderCode" placeholder="请输入" />
          </el-form-item>
          <el-form-item>
            <div class="params-select">
              <el-select v-model="params.type" placeholder="请选择" style="width: 135px" @change="init">
                <el-option v-for="(item, index) in type" :label="item" :value="Number(index)" />
              </el-select>
              <collaborators-query v-model:model-value="params.partnerId" :type="params.type" @flushed="init" />
            </div>
          </el-form-item>
          <el-form-item label="编号">
            <el-input v-model="params.slipCode" placeholder="请输入编号" style="flex: 1" @keyup.enter="init" @blur="init" />
          </el-form-item>
          <el-form-item>
            <div class="params-select">
              <el-select v-model="params.moneyType" placeholder="请选择" style="width: 135px" @change="init">
                <el-option label="应收金额" :value="1" />
                <el-option label="已收金额" :value="2" />
                <el-option label="未收金额" :value="3" />
              </el-select>
              <input-range v-model="params.amount" @change="init" />
            </div>
          </el-form-item>
          <el-form-item label="创建人">
            <created-by v-model="params.createId" @change="init" />
          </el-form-item>
          <el-form-item label="添加时间">
            <el-date-picker
              v-model="params.date"
              style="flex: 1"
              type="daterange"
              range-separator="—"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="YYYY-MM-DD"
              @change="init"
            >
            </el-date-picker>
          </el-form-item>
          <el-form-item label="业务类型">
            <el-select v-model="params.service" placeholder="请选择" style="flex: 1" @change="init">
              <el-option v-for="(item, index) in serviceType" :label="item" :value="Number(index)" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button :icon="RefreshRight" plain type="primary" @click="reset">重置</el-button>
            <el-button :icon="Download" type="primary" @click="exportTable"> 导出 </el-button>
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="total">合计金额<span>（所有筛选记录）</span></div>
    <div class="amount">
      <div>
        应收金额：<span>￥{{ count.plainMoney }}</span>
      </div>
      <div>
        已收金额：<span>￥{{ count.inMoney }}</span>
      </div>
      <div>
        未收金额：<span>￥{{ count.outMoney }}</span>
      </div>
    </div>
    <div class="table">
      <el-table :data="data" style="width: 100%" max-height="calc(100vh - 500px)">
        <el-table-column prop="slipCode" label="编号" width="160" />
        <el-table-column prop="businessType" label="业务类型" />
        <el-table-column prop="partner" label="合作方" min-width="260" />
        <el-table-column prop="city" label="核销状态" width="120">
          <template #default="scope">
            <el-tag type="warning" v-if="scope.row.cancelState == 1">{{ verificationType[scope.row.cancelState] }}</el-tag>
            <el-tag type="primary" v-else-if="scope.row.cancelState == 2">{{ verificationType[scope.row.cancelState] }}</el-tag>
            <el-tag type="success" v-else>{{ verificationType[scope.row.cancelState] }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="address" label="应收金额" width="120">
          <template #default="scope"> ￥{{ scope.row.plainMoney }} </template>
        </el-table-column>
        <el-table-column prop="address" label="已收金额" width="120">
          <template #default="scope"> ￥{{ scope.row.inMoney }} </template>
        </el-table-column>
        <el-table-column prop="zip" label="未收金额" width="120">
          <template #default="scope"> ￥{{ scope.row.outMoney }} </template>
        </el-table-column>
        <el-table-column prop="addDate" label="添加时间" width="180" />
        <el-table-column prop="orderCode" label="关联单据" width="180" />
        <el-table-column label="操作" fixed="right" width="230">
          <template #default="scope">
            <el-button type="primary" link size="small" @click="openDetail(scope.row)">详情</el-button>
            <el-button type="primary" link size="small" @click="toPath(scope.row)">支付流水</el-button>
            <el-button type="primary" link size="small" v-if="scope.row.outMoney > 0" @click="openPay(scope.row)"
              >去支付</el-button
            >
          </template>
        </el-table-column>
        <template #empty>
          <el-empty />
        </template>
      </el-table>
    </div>
    <div class="pagination">
      <el-pagination
        v-model:current-page="query.current"
        v-model:page-size="query.size"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="init"
        @current-change="init"
      />
    </div>
    <el-dialog v-model="detailVisible" width="500" center align-center :show-close="false">
      <template #title>
        <div class="modal-title">
          <custom-title title="订单收款单详情" /><el-icon @click="detailVisible = false">
            <Close />
          </el-icon>
        </div>
      </template>
      <div class="detail">
        <div>
          <div>
            订单收款单编码：<span class="black">{{ detail.slipCode }}</span>
          </div>
          <el-tag type="warning" v-if="detail.cancelState == 1">{{ verificationType[detail.cancelState] }}</el-tag>
          <el-tag type="primary" v-else-if="detail.cancelState == 2">{{ verificationType[detail.cancelState] }}</el-tag>
          <el-tag type="success" v-else>{{ verificationType[detail.cancelState] }}</el-tag>
        </div>
        <div>
          关联合作方<span class="black">{{ detail.partner }}</span>
        </div>
        <div>
          关联订单<span class="black">{{ detail.orderCode }}</span>
        </div>
        <div>
          应收金额<span class="black">￥{{ detail.plainMoney }}</span>
        </div>
        <div>
          已回款金额<span class="black">￥{{ detail.inMoney }}</span>
        </div>
        <div>
          未回款金额<span class="black">￥{{ detail.outMoney }}</span>
        </div>
      </div>
    </el-dialog>
    <el-dialog v-model="payVisible" width="600" center align-center :show-close="false" @close="resetPay">
      <template #title>
        <custom-title title="订单收款单支付" />
      </template>
      <div class="info">
        订单收款单编号：<span>{{ detail.slipCode }}</span>
        <div class="card">
          <div>
            <div>
              <div>关联合作方</div>
              <div>{{ detail.partner }}</div>
            </div>
            <div>
              <div>应收金额</div>
              <div>￥{{ detail.plainMoney }}</div>
            </div>
            <div>
              <div>已收金额</div>
              <div>￥{{ detail.inMoney }}</div>
            </div>
            <div>
              <div>未收金额</div>
              <div>￥{{ detail.outMoney }}</div>
            </div>
          </div>
        </div>
      </div>
      <el-form :model="payForm" label-position="top" ref="payFormRef" :rules="payRules">
        <el-form-item label="支付方式" prop="payType">
          <el-radio-group v-model="payForm.payType" @change="payFormRef.clearValidate()">
            <el-radio :value="1" label="账户支付" />
            <el-radio :value="2" label="现金" />
            <el-radio :value="3" label="预收款支付" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="本次收款金额" prop="money">
          <el-input v-model="payForm.money" />
        </el-form-item>
        <el-form-item label="收款日期" prop="receiptDate">
          <el-date-picker
            style="flex: 1"
            v-model="payForm.receiptDate"
            type="date"
            placeholder="请选择"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="收款账户" prop="accountId" v-if="payForm.payType == 1">
          <el-select v-model="payForm.accountId">
            <el-option
              v-for="item in account"
              :key="item.accountId"
              :value="item.accountId"
              :label="splicing(cleanArray([item.dictName, item.account, item.accountName]), '-')"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="支付凭证" prop="fileVos" v-if="payForm.payType != 3">
          <div>
            <el-upload class="avatar-uploader" multiple :show-file-list="false" :http-request="customRequest">
              <div class="list">
                <div class="code" v-for="item in payForm.fileVos" :key="item">
                  <img :src="item.fileUrl" />
                  <div class="del">
                    <el-icon @click.stop="delImg(item)">
                      <DeleteFilled />
                    </el-icon>
                  </div>
                </div>
                <el-icon class="upload" v-if="payForm.fileVos.length < 6">
                  <Plus />
                  <span>点击上传</span>
                </el-icon>
              </div>
            </el-upload>
            <div class="tip">注：支持{{ fileType }}格式，单张大小不超过{{ maxSize }}MB，只支持6张</div>
          </div>
        </el-form-item>
        <el-form-item label="预收款核销" v-if="payForm.payType == 3">
          <div class="pay-table">
            <div>
              <div>单号</div>
              <div>未使用金额</div>
              <div>本单使用</div>
            </div>
            <el-empty v-if="!advancesReceivedList.length" :image-size="80" />
            <el-form :rules="moneyRules" :model="payForm.advancesReceivedList" ref="moneyRef" inline-message>
              <el-scrollbar max-height="150px">
                <div class="table-row" v-for="item in advancesReceivedList" :key="item.slipId">
                  <div>{{ item.slipCode }}</div>
                  <div>￥{{ item.notUseMoney }}</div>
                  <div>
                    <el-form-item :prop="item.slipId">
                      <el-input placeholder="请输入" v-model="payForm.advancesReceivedList[item.slipId]" style="width: 150px" />
                    </el-form-item>
                  </div>
                </div>
              </el-scrollbar>
            </el-form>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="payVisible = false">取消</el-button>
          <el-button type="primary" @click="payComfirm"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { RefreshRight, Plus, Download } from "@element-plus/icons-vue";
import { getList, pay, getCount, exportTableData } from "@/apis/invoices";
import { ElMessage } from "element-plus";
import { getList as getMyAccountList } from "@/apis/myAccount";
import { available } from "@/apis/invoices/order";
import { type, verificationType } from "@/utils/config";
import { splicing, cleanArray } from "@/utils";
import { useRoute } from "vue-router";
import uploadFile from "@/utils/uploadFile";
import exportExcel from "@/utils/exportExcel";

const route = useRoute();
const emit = defineEmits(["toPayment"]);
const toPath = item => {
  emit("toPayment", {
    slipCode: item.slipCode,
    slipType: 1
  });
};
const moneyRef = ref(null); // 使用预收款核销金额

const serviceType = {
  1: "订单付款",
  11: "售后收款"
};
const payFormRef = ref(null);
const options = ref([]);
const query = ref({
  current: 1,
  size: 10
});
const account = ref([]); // 收款账户
const params = ref({
  serviceType: 1,
  slipCode: route.query.slipCode,
  amount: []
});
/**
 * 重置筛选表单
 */
const reset = () => {
  params.value = {
    serviceType: 1
  };
  init();
};
/**
 * 重置支付表单
 */
const resetPay = () => {
  payFormRef.value.resetFields();
  payForm.value = {
    payType: 1,
    fileVos: [],
    advancesReceivedList: {}
  };
};
const detailVisible = ref(false);
const payVisible = ref(false);

const payForm = ref({
  payType: 1,
  fileVos: [],
  advancesReceivedList: {}
});
const advancesReceivedList = ref([]);
const detail = ref({});
const total = ref(0);
const data = ref([]);
const count = ref({
  outMoney: 0,
  inMoney: 0,
  plainMoney: 0
});
const payRules = {
  payType: [{ required: true, message: "请选择支付方式", trigger: "blur" }],
  receiptDate: [{ required: true, message: "请选择收款日期", trigger: "blur" }],
  fileVos: [{ required: true, message: "请上传收款凭证", trigger: "blur" }],
  money: [
    { required: true, message: "请输入收款金额", trigger: "blur" },
    { pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: "请输入正确的金额", trigger: "blur" }
  ],
  accountId: [{ required: true, message: "请选择收款账户", trigger: "blur" }]
};
const delImg = img => {
  payForm.value.fileVos = payForm.value.fileVos.filter(item => item.fileId != img.fileId);
};
const openDetail = item => {
  detailVisible.value = true;
  detail.value = { ...item };
};
const moneyRules = ref({});

/**
 * 校验使用金额
 */
const verfy = (rule, value, callback) => {
  const max = Number(advancesReceivedList.value.filter(v => v.slipId == rule.field)[0].notUseMoney);
  if (value > max) {
    callback(new Error("不能大于未使用金额"));
  } else {
    callback();
  }
};
/**
 * 打开支付弹窗
 */
const openPay = async item => {
  isImgMax.value = false;
  payVisible.value = true;
  detail.value = { ...item };
  const res = await available(item.partnerId);
  advancesReceivedList.value = res.data;
  // 动态生成校验规则
  advancesReceivedList.value.forEach(v => {
    moneyRules.value[v.slipId] = [
      { pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: "请输入正确的金额", trigger: "blur" },
      { validator: verfy, trigger: "blur" }
    ];
  });
};
const isImgMax = ref(false);
const maxSize = ref(20);
const fileType = ref("JPG/JPEG/PNG");
const customRequest = async options => {
  const type = ["image/jpg", "image/jpeg", "image/png"];
  const { file } = options;
  if (!type.includes(file.type)) {
    ElMessage.error("图片格式错误");
    return false;
  } else if (file.size / 1024 / 1024 > maxSize.value) {
    ElMessage.error(`图片大小不能超过${maxSize.value}MB!`);
    return false;
  }
  const fileInfo = await uploadFile(options);
  if (payForm.value.fileVos.length < 6) {
    payForm.value.fileVos.push({ fileUrl: fileInfo.url, fileName: fileInfo.name, fileId: fileInfo.uid });
  } else {
    if (!isImgMax.value) ElMessage.error("最多上传6张图片");
    isImgMax.value = true;
  }
};
const payComfirm = () => {
  const next = async arr => {
    const res = await pay({
      ...payForm.value,
      type: undefined,
      slipId: detail.value.slipId,
      money: Number(payForm.value.money),
      advancesReceivedList: arr
    });
    if (res.code == 200) {
      payVisible.value = false;
      init();
      ElMessage.success("操作成功");
    }
  };
  payFormRef.value.validate(async valid => {
    if (!valid) return;
    if (payForm.value.payType == 3) {
      if (!advancesReceivedList.value.length) return ElMessage.error("没有使用的单据");
      const money = Object.keys(payForm.value.advancesReceivedList);
      if (!money.length) return ElMessage.error("没有使用的预收款金额");
      moneyRef.value.validate(async v => {
        if (!v) return;
        const arr = advancesReceivedList.value
          .filter(v => money.includes(v.slipId))
          .map(v => ({ slipId: v.slipId, money: payForm.value.advancesReceivedList[v.slipId] }));
        next(arr);
      });
    } else {
      next();
    }
  });
};
const getParams = () => {
  const minAmount = params.value.amount ? params.value.amount[0] : undefined;
  const maxAmount = params.value.amount ? params.value.amount[1] : undefined;
  const createdTimeBegin = params.value.date ? params.value.date[0] + " 00:00:00" : undefined;
  const createdTimeEnd = params.value.date ? params.value.date[1] + " 23:59:59" : undefined;
  const paramsData = {
    ...params.value,
    minAmount,
    maxAmount,
    createdTimeBegin,
    createdTimeEnd
  };
  delete paramsData.date;
  delete paramsData.amount;
  return paramsData;
};
const init = async () => {
  try {
    const res = await getList(query.value, getParams());
    data.value = res.data.list;
    total.value = res.data.total;
  } catch (error) {}
  try {
    const counts = await getCount(getParams());
    count.value = counts.data ? counts.data : { outMoney: 0, inMoney: 0, plainMoney: 0 };
  } catch (error) {}
};
const exportTable = async () => {
  try {
    const res = await exportTableData(query.value, getParams());
    exportExcel(res, "订单收款单列表");
  } catch (error) {}
};
const getAccount = async () => {
  const res = await getMyAccountList({ current: 1, size: 100000 }, { status: 1 });
  account.value = res.data.list;
};
onMounted(() => {
  getAccount();
  init();
});
</script>

<style lang="scss" scoped>
@import "../comon.scss";
</style>
